﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIT.Controls;
using UIT.Controls.Containers;
using UIT.Markup;
using UIT.VisualStates;
using UIT.Events.Keyboard;

namespace UIT.Web.Controls.Html
{
    public class HtmlControl : IWebControl, IDrawableControl
    {
        public HtmlControl(string tagName, bool isContainer)
        {
            this.tagName = tagName;
            this.isContainer = isContainer;
            Events = new Events.Events();
            KeyCommandBindings = new DisposableObservableCollection<IControl, KeyCommandBinding>(this);
        }

        private bool isContainer;
        private string tagName;

        internal string TagName { get { return tagName; } }

        public bool NeedFullClosingTag { get; set; }

        #region IWebControl Members

        public WebControlType WebType
        {
            get { return WebControlType.Html; }
        }

        #endregion

        #region IControl Members

        public string Id
        {
            get;
            set;
        }

        public bool IsContainer
        {
            get { return isContainer; }
        }

        public UIT.Controls.ControlType Type
        {
            get { return UIT.Controls.ControlType.Specific; }
        }

        public string StyleKey
        {
            get;
            set;
        }

        private object dataContext;

        public object DataContext
        {
            get { return dataContext; }
            set
            {
                dataContext = value;
                OnPropertyChanged("DataContext");
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region IControl Members

        private IContainer parent;

        public IContainer Parent
        {
            get { return parent; }
            set
            {
                if (parent != null)
                    ((IControlContainer)parent).Children.Remove(this);
                parent = value;
                if (parent != null)
                    ((IControlContainer)parent).Children.Add(this);
                OnPropertyChanged("Parent");
            }
        }


        #endregion

        #region IControl Members

        private bool isEnabled;

        public bool IsEnabled
        {
            get { return isEnabled; }
            set
            {
                isEnabled = value;
                OnPropertyChanged("IsEnabled");
            }
        }

        private bool isVisible;

        public bool IsVisible
        {
            get { return isVisible; }
            set
            {
                isVisible = value;
                OnPropertyChanged("IsVisible");
            }
        }

        #endregion

        #region ISupportInitializeNotification Members

        public event EventHandler Initialized;

        public bool IsInitialized
        {
            get;
            private set;
        }

        #endregion

        #region ISupportInitialize Members

        public void BeginInit()
        {
            Initializing = true;
        }

        public void EndInit()
        {
            Initializing = false;
            IsInitialized = true;
            if (Initialized != null)
                Initialized(this, EventArgs.Empty);
        }

        #endregion

        protected bool Initializing { get; private set; }

        #region IDisposable Members

        public void Dispose()
        {
            Initialized = null;
        }

        #endregion

        #region IControl Members


        public object Metadata
        {
            get;
            set;
        }

        #endregion

        #region IControl Members


        public virtual bool IsDrawable
        {
            get { return true; }
        }

        #endregion

        #region IDrawableControl Members

        public Style.Style Style
        {
            get;
            set;
        }

        #endregion


        public Style.Unit Height
        {
            get
            {
                return UIT.Style.Style.GetHeight(this);
            }
            set
            {
                UIT.Style.Style.SetHeight(this, value);
            }
        }

        public Style.Unit Width
        {
            get
            {
                return UIT.Style.Style.GetWidth(this);
            }
            set
            {
                UIT.Style.Style.SetWidth(this, value);
            }
        }

        public Style.Brush Background
        {
            get
            {
                return UIT.Style.Style.GetBackground(this);
            }
            set
            {
                UIT.Style.Style.SetBackground(this, value);
            }
        }

        #region IDrawableControl Members


        public Style.Thickness Margin
        {
            get
            {
                return UIT.Style.Style.GetMargin(this);
            }
            set
            {
                UIT.Style.Style.SetMargin(this, value);
            }
        }

        #endregion

        #region IControl Members


        public Events.Events Events
        {
            get;
            set;
        }

        #endregion

        #region IControl Members


        public IDisposableObservableCollection<IControl, KeyCommandBinding> KeyCommandBindings
        {
            get;
            private set;
        }

        IDisposableObservableCollection<IControl, KeyCommandBinding> IContainer<IControl, KeyCommandBinding>.Children
        {
            get { return KeyCommandBindings; }
        }

        #endregion

        #region IControl Members


        public int? TabIndex
        {
            get;
            set;
        }

        #endregion

        #region IControl Members


        public IUitContext Context
        {
            get { return UIT.Context.Current; }
        }

        #endregion

        #region IBindingContainer Members

        private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>();

        public Binding GetBinding(string propertyName)
        {
            Binding binding;
            bindings.TryGetValue(propertyName, out binding);
            return binding;
        }

        public void SetBinding(string propertyName, Binding binding)
        {
            Binding originalBinding = GetBinding(propertyName);
            if (originalBinding != null)
                originalBinding.Dispose();
            bindings[propertyName] = binding;
        }

        public bool RemoveBinding(string propertyName)
        {
            Binding originalBinding = GetBinding(propertyName);
            if (originalBinding == null)
                return false;
            originalBinding.Dispose();
            return bindings.Remove(propertyName);

        }

        #endregion


        public void OnPreInit()
        {
            if (PreInit != null)
                PreInit(this, EventArgs.Empty);
        }

        public void OnPostInit()
        {
            if (PostInit != null)
                PostInit(this, EventArgs.Empty);
        }

        public event EventHandler PreInit;

        public event EventHandler PostInit;

        public void OnPreLoad()
        {
            if (PreLoad != null)
                PreLoad(this, EventArgs.Empty);
        }

        public void OnPostLoad()
        {
            if (PostLoad != null)
                PostLoad(this, EventArgs.Empty);
        }

        public event EventHandler PreLoad;

        public event EventHandler PostLoad;
        private DisposableObservableCollection<IControl, VisualState> visualStates;

        public string AclResource { get; set; }


        public IDisposableObservableCollection<IControl, VisualStates.VisualState> VisualStates
        {
            get
            {
                if (visualStates == null)
                    visualStates = new DisposableObservableCollection<IControl, VisualState>(this);
                return visualStates;
            }
        }

        IDisposableObservableCollection<IControl, VisualStates.VisualState> IContainer<IControl, VisualState>.Children
        {
            get { return VisualStates; }
        }
    }
}
